package io.github.wppli.domain.recommond.rservice.referral;

import cc.jq1024.middleware.redisson.IRedissonService;
import io.github.wppli.domain.recommond.repository.IProductRepository;
import io.github.wppli.domain.recommond.rservice.AbstractProductRecommendService;
import io.github.wppli.domain.recommond.rservice.datamodel.DataModelService;
import lombok.extern.slf4j.Slf4j;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.CachingRecommender;
import org.apache.mahout.cf.taste.impl.recommender.GenericItemBasedRecommender;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.ItemSimilarity;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.List;

/**
 * 产品推荐服务
 * @author li--jiaqiang 2025−03−14
 */
@Slf4j
@Service
public class ProductRecommendService extends AbstractProductRecommendService {

    public final DataModelService dataModelService;

    public ProductRecommendService(IProductRepository productRepository, IRedissonService redissonService, DataModelService dataModelService) {
        super(productRepository, redissonService);
        this.dataModelService = dataModelService;
    }

    /**
     * 商品推荐：基于用户关注物品的相似性
     * @param itemId       目标物品ID
     * @param recommendNum 推荐数量
     */
    public List<RecommendedItem> recommendProductsByItemCF(Long itemId, int recommendNum) throws ClassNotFoundException, TasteException {
        DataModel dataModel = dataModelService.getDataModelFromDataSource(
                "user_behaviors", "user_id", "product_id","behavior_score", "create_time"
        );
        // 1. 计算物品相似度（这里物品是商品）
        ItemSimilarity itemSimilarity = new PearsonCorrelationSimilarity(dataModel);
        // 2. 构建推荐器，使用基于物品的协同过滤推荐
        CachingRecommender recommender = new CachingRecommender(
                new GenericItemBasedRecommender(dataModel, itemSimilarity)
        );
        // 3. 生成推荐结果
        return recommender.recommend(itemId, recommendNum);
    }


    /**
     * 根据相似得用户推荐商品 -》 相似用户也喜欢的商品
     * @param userId 用户id
     * @param neighborhoodCount 邻居数量
     * @param recommendCount 推荐数量
     * @return 推荐商品列表
     */
    @Override
    public List<RecommendedItem> recommendProductsByUserCF(@NotNull Long userId, int neighborhoodCount, int recommendCount) throws ClassNotFoundException, TasteException {
        if (neighborhoodCount <= 0) {
            throw new IllegalArgumentException("neighborhoodCount must be greater than 0");
        }
        if (recommendCount <= 0) {
            throw new IllegalArgumentException("recommendCount must be greater than 0");
        }
        DataModel dataModel = dataModelService.getDataModelFromDataSource(
                "user_behaviors", "user_id", "product_id","behavior_type", "create_time"
        );
        // 计算用户相似度
        UserSimilarity similarity = new PearsonCorrelationSimilarity(dataModel);
        // 计算最近10个邻居
        UserNeighborhood neighborhood = new NearestNUserNeighborhood(neighborhoodCount, similarity, dataModel);
        // 获取用户 userId 的邻居
        // long[] userNeighborhood = neighborhood.getUserNeighborhood(userId);
        Recommender recommender = new CachingRecommender(
                new GenericUserBasedRecommender(dataModel, neighborhood, similarity)
        );
        return recommender.recommend(userId, recommendCount);
    }



}